#include "lexer.h"
#include "parser.h"
struct vm_State{
        struct token regs[8];
        int IP;
};


typedef int(* vm_Opfxn)(struct vm_State*, union value, union value);

struct vm_Instruction{
	vm_Opfxn fxn;
	union value a;
	union value b;
};

struct vm_Program{
	struct vm_Instruction *insts;
	int ninsts;
};

int main ()
{
	struct vm_State vm;
	int lines;	
	struct list *ll=lex(stdin,stdout,stderr);
	
	struct vm_Instruction instructs[lines];
	int i;
	for(i=1;i<=line;i++){
		vm_parseinstruction(instructs[i-1],ll);
	}
	int j=1;
	int jmp;
	while(j<=line){
		jmp=instructs[j-1].fxn(vm,instructs[j-1].a,instructs[j-1].b);
		if(jmp>0){
			j=jmp;
		}
		else
			j++;
	}
			
	
	





	delete_list(ll);
}

int vm_parseinstruction (struct vm_Instruction inst, struct list ll) {
	struct token t = token_popfront (ll);

	if (t.type != OPCODE) {
                fprintf (stderr, "OPCODE expected as first instruction");

                return 0;
        }

        if (t.v.op == MOVE){ 
	//	free(t);
                return vm_parseMOV (inst,ll);
	}
        else if (t.v.op == ADD){
	//	free(t);
                return vm_parseADD (inst, ll);
	}
	else if (t.v.op == SWAP){
	//	free(t);
		return vm_parseSWAP (inst, ll);
	}
        else if (t.v.op == CLR){
	//	free(t);
                return vm_parseCLR (inst, ll);
	}
	else if (t.v.op == JZ){
	//	free(t);
		return vm_parseJZ (inst, ll);
	}
	else if(t.v.op == JNZ) {
	//	free(t);
		return vm_parseJNZ (inst, ll);
	}
        else if (t.v.op == SUB){
	//	free(t);
                return vm_parseSUB (inst, ll);
	}
        else if (t.v.op == MULT){
	//	free(t);
                return vm_parseMULT (inst, ll);
	}
	else if (t.v.op == DIV){
	//	free(t);
		return vm_parseDIV (inst, ll);
	}
	else if (t.v.op == GET){
	//	free(t);
		return vm_parseGET (inst, ll);
	}
	else if (t.v.op == PUT){
	//	free(t);
		return vm_parsePUT (inst, ll);
	}
//	else if (t.v.op == DEC){
	//	free(t);
//		return vm_parseDEC (inst, ll);
//	}
//	else if (t.v.op == PRT){
	//	free(t);
//		return vm_parsePRT (inst, ll);
//	}
	
	return 0;
}







